Skip to content

Release dev → main: governance loading, hierarchy cache, agent rules/docs#183

Merged
djm81 merged 21 commits intomainfrom
dev
Apr 13, 2026
Merged

Release dev → main: governance loading, hierarchy cache, agent rules/docs#183
djm81 merged 21 commits intomainfrom
dev

Conversation

@djm81
Copy link
Copy Markdown
Contributor

@djm81 djm81 commented Apr 12, 2026

Summary

Promote dev to main after merging PR #182 (deterministic agent governance loading). This release train also includes PR #180 (project-runtime OpenSpec recovery) and PR #179 (GitHub hierarchy cache script and governance), plus follow-up fixes on the governance/pre-commit path.

Refs:

Scope

  • Bundle source changes under packages/
  • Registry/manifest changes (registry/index.json, packages/*/module-package.yaml)
  • CI/workflow changes (.github/workflows/*)
  • Documentation changes (docs/*, README.md, AGENTS.md)
  • Security/signing changes (scripts/sign-modules.py, scripts/verify-modules-signature.py)

Note: .github/copilot-instructions.md changed; workflow YAML under .github/workflows/ did not.

Bundle Impact

No bundle or registry changes in origin/main..origin/dev (no packages/ or registry/ diffs). Version lines below are unchanged for this promotion.

  • nold-ai/specfact-project: unchanged
  • nold-ai/specfact-backlog: unchanged
  • nold-ai/specfact-codebase: unchanged
  • nold-ai/specfact-spec: unchanged
  • nold-ai/specfact-govern: unchanged

Validation Evidence

Attach snippets or workflow run links after running the gates below on this branch (or cite green checks from the merged feature PRs).

Required local gates

  • hatch run format
  • hatch run type-check
  • hatch run lint
  • hatch run yaml-lint
  • hatch run check-bundle-imports
  • hatch run contract-test
  • hatch run smart-test (or hatch run test)

Signature + version integrity (required)

  • hatch run verify-modules-signature --require-signature --payload-from-filesystem --enforce-version-bump
  • Changed bundle versions were bumped before signing
  • Manifests re-signed after bundle content changes

No bundle content changed in this range; confirm signature gate still passes on dev before merge.

CI and Branch Protection

  • PR orchestrator jobs expected:
    • verify-module-signatures
    • quality (3.11)
    • quality (3.12)
    • quality (3.13)
  • Branch protection required checks are aligned with the above

Docs / Pages

  • Bundle/module docs updated in this repo (docs/)
  • Pages workflow impact reviewed (docs-pages.yml, if changed)
  • Cross-links from specfact-cli docs updated (if applicable)

Checklist

  • Self-review completed
  • No unrelated files or generated artifacts included
  • Backward-compatibility/rollout notes documented (if needed)

djm81 and others added 17 commits April 9, 2026 22:28
…rarchy-cache

feat: add GitHub hierarchy cache sync
Recovered openspec/changes/project-runtime-01-safe-artifact-write-policy/
from bd07b05 (removed in f174ed0 during review fixes). CHANGE_ORDER.md
already references this change and specfact-cli#490.

Made-with: Cursor
…-openspec

chore(openspec): restore project-runtime-01-safe-artifact-write-policy
Complete OpenSpec change governance-04-deterministic-agent-governance-loading:
- Compact AGENTS.md/CLAUDE.md bootstrap; Cursor/Copilot alias surfaces
- Canonical docs/agent-rules/ INDEX and domain rule files; docs nav
- validate_agent_rule_applies_when.py; pre-commit and hierarchy-cache hardening
- Unit tests for agent rules, applies_when validator, and cache script
- openspec/config.yaml and change artifacts (TDD_EVIDENCE, validation)

Refs: #181, #163, #178; nold-ai/specfact-cli#494
Made-with: Cursor
…tic-agent-governance-loading

feat(governance): deterministic agent governance loading (governance-04)
@djm81 djm81 self-assigned this Apr 12, 2026
@djm81 djm81 added enhancement New feature or request dependencies Pull requests that update a dependency file labels Apr 12, 2026
@djm81 djm81 moved this to In Progress in SpecFact CLI Apr 12, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Release dev → main: governance loading, hierarchy cache, agent rules; no bundle/registry or public module API changes.

Bundle and module surface

  • No semver or module-package.yaml changes; no exports/APIs altered in packages/ or registry/.
  • New developer/runtime helpers (not user-facing CLI commands):
    • src/specfact_cli_modules/dev_bootstrap.apply_specfact_workspace_env(repo_root): sets SPECFACT_MODULES_REPO and, when resolvable, SPECFACT_REPO_ROOT for dev/test runs.
    • dev-test harness and pre-commit flows call apply_specfact_workspace_env to anchor module discovery to the checkout.
  • New helper/tooling scripts (dev support only):
    • scripts/sync_github_hierarchy_cache.py — repo-local deterministic Epic/Feature hierarchy cache sync (markdown + state JSON), fingerprint-based fast-exit, recursive pagination, deterministic render; writes .specfact/backlog/github_hierarchy_cache.md and .specfact/backlog/github_hierarchy_cache_state.json.
    • scripts/validate_agent_rule_applies_when.py — validator for docs/agent-rules frontmatter applies_when.
    • scripts/pre_commit_quality_checks.sh and scripts/pre_commit_code_review.py — refactored pre-commit block staging and code-review gate (now produces .specfact/code-review.json on success).
    • tools/contract_first_smart_test.py — staged-path awareness and status command to gate contract tests.
  • Tests updated/added to cover the above scripts and governance docs; AGENTS.md newline added to satisfy tests.

Manifest and integrity

  • No module-version bumps or registry/index.json changes; module/package manifests unchanged.
  • Pre-commit and local quality workflow tightened:
    • .pre-commit-config.yaml restructured: fail_fast: true; Block1 (format, yaml-if-staged, bundle-import, lint-if-staged) and Block2 (code review + contract tests).
    • pre-commit helper now enforces creation/consumption of .specfact/code-review.json; code-review gate enforces report presence and non-zero-timeout handling.
  • Checklist in PR notes includes remaining required gates before merge: format, type-check, lint, yaml-lint, bundle import checks, contract/smart tests, module signature verification and version-bump/resign steps (verify-modules-signature expectations remain to be completed).

Cross-repo / dev-deps / import contracts

  • No breaking import or runtime API changes expected vs specfact-cli; dev changes assume parity with core:
    • Adds environment defaults (pyproject.toml: SPECFACT_MODULES_REPO = "{root}") and apply_specfact_workspace_env to prefer the local modules checkout and to set SPECFACT_REPO_ROOT when a paired core checkout is present.
    • Tests and bootstrap now rely on apply_specfact_workspace_env instead of ad-hoc sibling lookup.
  • New dev dependency added for Hatch default env: beartype>=0.22.0 (annotation/runtime contracts used by validators) and json5>=0.9.28; pyproject.toml lists these in [tool.hatch.envs.default]. Ensure CI/consumers add these to hatch envs as required.
  • Project-runtime safe-write change documents expect a companion core capability (profile-04-safe-project-artifact-writes); modules adopt the contract but do not vendor core implementation.

Documentation and site / navigation

  • Major documentation reorganization to docs/agent-rules/ with numbered rule files and a deterministic loader:
    • docs/agent-rules/INDEX.md (canonical index, always_load) and rule files 05–80 covering non-negotiable checklist, session bootstrap, repository context, worktrees/branching, OpenSpec/TDD, quality gates, GitHub change governance, release/docs, and a guidance catalog.
    • AGENTS.md reduced to a compact mandatory bootstrap that delegates to docs/agent-rules/INDEX.md.
    • Aliases/redirects added: .cursorrules and .github/copilot-instructions.md and CLAUDE.md referencing the canonical rule index.
    • docs/_data/nav.yml: adds top-level "Agent Governance" nav entries.
  • README updated to document Block 1/Block 2 pre-commit sequencing, added hatch commands (check-bundle-imports, specfact code review run --json …) and clarified staged-path scoping for the code-review helper.
  • OpenSpec artifacts and CHANGE_VALIDATION / TDD_EVIDENCE updated for:
    • governance-03-github-hierarchy-cache (archived) — spec, proposal, tasks, design, TDD evidence and initial validation recorded.
    • governance-04-deterministic-agent-governance-loading (active, PENDING/BLOCKED) — spec and design add deterministic agent-governance loading, rule frontmatter schema and INDEX-based loader; CHANGE_VALIDATION marks full repo SpecFact code review FAIL with 934 findings (changed-scope passes).
    • project-runtime-01-safe-artifact-write-policy — module-side adoption spec, tasks, and validation PASS recorded.
  • Documentation changes include explicit canonical paths for the hierarchy cache (.specfact/backlog/github_hierarchy_cache.md and its state JSON) and instructions when to refresh it (cache-first behavior).

OpenSpec change IDs and scenario coverage

  • governance-03-github-hierarchy-cache (archive): adds deterministic repo-local hierarchy cache, sync script, and cache-first backlog-sync semantics.
  • governance-04-deterministic-agent-governance-loading: introduces deterministic bootstrap sequence (AGENTS.md → docs/agent-rules/INDEX.md → selected rule files), frontmatter schema, session-bootstrap cache refresh semantics, and agent-rule validation tooling; validation shows full-specfact gate failing (934 findings) and is recorded as PENDING/BLOCKED.
  • project-runtime-01-safe-artifact-write-policy: modules-side safe-write adoption companion to core profile; mandates safe-write contract use in backlog-add/backlog-sync and other runtime artifact writers.

Known issues / reviewer action items (from review thread)

  • beartype is required by scripts/validate_agent_rule_applies_when.py and must be declared in the default Hatch env (pyproject.toml already updated in this PR to include beartype; confirm Hatch env used by CI/maintainers).
  • sync_github_hierarchy_cache.py:
    • Fingerprint must include only fields that affect rendered output (exclude updated_at, include title/labels/URL/summary/parent/child numbers) and use deterministic ordering.
    • Ensure robust nested pagination for subIssues (use pageInfo endCursor/hasNextPage iteration).
  • validate_agent_rule_applies_when.py:
    • Wrap file read operations to record/continue on read errors; stricter list-type validation (reject non-string list elements) and avoid coercing items to str.
  • dev_bootstrap.apply_specfact_workspace_env currently sets env vars; tests expect it to overwrite stale env values to reflect current checkout — confirm behavior matches CI expectations.
  • pre-commit hooks and pre_commit_quality_checks.sh:
    • Expand code-review gate to accept all relevant staged paths (not only Python) and pass them to pre_commit_code_review.py.
    • Narrow safe-change short-circuit so pipeline-defining files cannot bypass review/contract tests.
  • Tests: small fixes requested (fixtures, cleanup, additional happy-path tests) and several markdown lint fixes across docs and proposals.
  • Remaining gate: full-scope SpecFact code review fails (934 findings); remediation or approved exception required before merge. Signature/version integrity checklist items (verify-modules-signature, version bumps/resign) remain to be completed.

Recommended maintainer checklist before merge (summarized)

  • Run full quality gates locally/CI: format, type-check, lint, yaml-lint, hatch run check-bundle-imports, contract/smart tests, full specfact code review (full scope).
  • Address the 934 findings from full-scope SpecFact code review or record an approved exception.
  • Ensure beartype (and json5) are available in hatch default env in CI; verify scripts requiring beartype run in fresh checkouts.
  • Confirm pre-commit hook behavior: block sequencing, staged-path filtering, and safe-change short-circuit are correct and do not let critical files bypass Block 2.
  • Complete module signature/version verification and any required version-bump/resign steps per the PR checklist.

Walkthrough

Consolidates repository governance into a deterministic agent-rule system under docs/agent-rules/ (INDEX + rule files + checklist), compacts AGENTS.md to a bootstrap contract, restructures pre-commit hooks into staged Block 1/Block 2 flow, adds a repo-local GitHub hierarchy cache + sync script, introduces agent-rule validation and many OpenSpec governance/spec artifacts, and updates tests and CI-environment wiring.

Changes

Cohort / File(s) Summary
Agent Governance Surface
AGENTS.md, CLAUDE.md, .cursorrules, .github/copilot-instructions.md
Replaced verbose guidance with a compact mandatory bootstrap contract and alias/redirect surfaces pointing to docs/agent-rules/INDEX.md as canonical guidance.
Agent Rules Documentation
docs/agent-rules/INDEX.md, docs/agent-rules/05-non-negotiable-checklist.md, docs/agent-rules/10-session-bootstrap.md, docs/agent-rules/20-repository-context.md, docs/agent-rules/30-worktrees-and-branching.md, docs/agent-rules/40-openspec-and-tdd.md, docs/agent-rules/50-quality-gates-and-review.md, docs/agent-rules/60-github-change-governance.md, docs/agent-rules/70-release-commit-and-docs.md, docs/agent-rules/80-current-guidance-catalog.md
Added a deterministic rule index and eight focused rule files with machine-readable frontmatter (applies_when, priority, blocking, etc.) and a non-negotiable checklist; defines bootstrap/load/precedence semantics.
GitHub Hierarchy Cache & Validator
scripts/sync_github_hierarchy_cache.py, scripts/validate_agent_rule_applies_when.py, openspec/.../governance-03*
Added a fingerprinted repo-local Epic/Feature hierarchy cache with deterministic markdown + state file and a validator for applies_when signals; OpenSpec artifacts and tests accompany the cache/spec.
Pre-commit & Quality Gate Refactor
.pre-commit-config.yaml, scripts/pre-commit-quality-checks.sh, scripts/pre_commit_code_review.py, tools/contract_first_smart_test.py
Split pre-commit into Block 1 (format/yaml/bundle/lint) and Block 2 (code-review + contract tests); refactored pre-commit driver into subcommands, updated review script to prepare report path and apply workspace env, and added contract-test status support.
Workspace / Dev Bootstrap
pyproject.toml, src/specfact_cli_modules/dev_bootstrap.py, tests/conftest.py, tests/unit/test_dev_bootstrap.py
Added SPECFACT_MODULES_REPO hatch env var, apply_specfact_workspace_env() to set workspace env vars deterministically, and updated tests/conftest to use the new bootstrap behavior and core-resolution checks.
OpenSpec Governance & Runtime Policies
openspec/changes/.../governance-04*, openspec/changes/.../project-runtime-01*, openspec/config.yaml, openspec/specs/github-hierarchy-cache/spec.md, openspec/specs/backlog-sync/spec.md
Introduced governance-04 (deterministic agent governance loading) and project-runtime-01 (safe artifact write policy) OpenSpec artifacts, updated config/specs to require cache-first backlog/hierarchy behavior and safe-write runtime requirements.
Docs Navigation & Readme
docs/_data/nav.yml, README.md
Inserted "Agent Governance" nav section and updated README to describe Block 1/Block 2 code-review flow and new local quality-gate steps.
Tests
tests/__init__.py, tests/unit/docs/test_agent_rules_governance.py, tests/unit/scripts/test_sync_github_hierarchy_cache.py, tests/unit/scripts/test_validate_agent_rule_applies_when.py, tests/unit/scripts/test_pre_commit_code_review.py, tests/unit/test_pre_commit_quality_parity.py, tests/unit/tools/test_contract_first_smart_test.py, plus others
Added comprehensive unit tests for agent-rule frontmatter/INDEX, cache fingerprinting and behavior, validator script, pre-commit/code-review parity, contract-test status, and updated dev-bootstrap tests.
Large New Script
scripts/sync_github_hierarchy_cache.py
New, substantial script implementing GraphQL fetch, deterministic fingerprinting, recursive child retrieval, markdown rendering, and state-file fast-exit logic.
Misc Config & Tooling
pyproject.toml, .pre-commit-config.yaml, openspec/CHANGE_ORDER.md
Hatch env additions (beartype, json5, validate-agent-rule-signals script), pre-commit fail_fast and reorganized hooks, and CHANGE_ORDER updates listing new governance changes.

Sequence Diagram(s)

sequenceDiagram
    actor Agent
    participant AGENTS as AGENTS.md
    participant Bootstrap as Session Bootstrap
    participant Cache as GitHub Hierarchy Cache
    participant Index as docs/agent-rules/INDEX.md
    participant Rules as docs/agent-rules/*.md

    Agent->>AGENTS: read bootstrap contract
    AGENTS->>Bootstrap: trigger session-bootstrap checks
    Bootstrap->>Cache: check .specfact/backlog/github_hierarchy_cache.md freshness
    alt cache missing or stale
        Bootstrap->>Cache: run scripts/sync_github_hierarchy_cache.py
        Cache->>Cache: fetch issues via gh api graphql
        Cache->>Cache: compute fingerprint and write markdown + state
    end
    Bootstrap->>Index: load INDEX.md
    Index->>Rules: select applies_when-matching rule files (05–80)
    Rules->>Agent: enforce non-negotiable checklist and quality gates before implementation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested labels

documentation, backlog

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6cd6564cff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 25

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
openspec/specs/backlog-sync/spec.md (1)

7-33: ⚠️ Potential issue | 🟠 Major

Pin the hierarchy-cache path contract explicitly in spec text.

repo-local hierarchy cache is currently ambiguous. Cross-repo tooling/tests rely on the canonical files (.specfact/backlog/github_hierarchy_cache.md and state JSON). Please make the path contract explicit here to prevent adapter drift between modules and specfact-cli.

Suggested spec wording update
-The system SHALL provide `specfact backlog sync` command for bidirectional backlog synchronization, and related governance workflows SHALL be able to resolve current Epic and Feature planning metadata from the repo-local hierarchy cache before performing manual GitHub lookups.
+The system SHALL provide `specfact backlog sync` command for bidirectional backlog synchronization, and related governance workflows SHALL resolve current Epic and Feature planning metadata from `.specfact/backlog/github_hierarchy_cache.md` (with deterministic state tracked in `.specfact/backlog/github_hierarchy_cache_state.json`) before performing manual GitHub lookups.

 #### Scenario: Cache-first hierarchy lookup for parent issue assignment
 - **GIVEN** a contributor needs a parent Feature or Epic while preparing GitHub sync metadata
-- **WHEN** the local hierarchy cache is present and current
+- **WHEN** `.specfact/backlog/github_hierarchy_cache.md` is present and current
 - **THEN** the contributor can resolve the parent relationship from the cache without an additional GitHub lookup
As per coding guidelines: “`openspec/**/*.md`: Specification truth: proposal/tasks/spec deltas vs. bundle behavior, CHANGE_ORDER, and drift vs. shipped modules or docs.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/specs/backlog-sync/spec.md` around lines 7 - 33, Update the spec
text to explicitly pin the repo-local hierarchy cache path and state file names
so adapters and specfact-cli share a canonical contract: replace ambiguous
instances of "repo-local hierarchy cache" with the explicit paths
`.specfact/backlog/github_hierarchy_cache.md` for the human-readable hierarchy
and the accompanying state JSON (e.g.,
`.specfact/backlog/github_hierarchy_cache.state.json`), and add a short sentence
in the "Cache-first hierarchy lookup for parent issue assignment" scenario
noting that tools MUST read/write those exact files and only fall back to GitHub
when those files are missing or stale; reference the command `specfact backlog
sync` and the alias `specfact backlog ceremony sync` so the change is visible to
consumers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/agent-rules/50-quality-gates-and-review.md`:
- Around line 39-49: The quality gate list omits the bundle-import validation
step; update the "Quality gate order" sequence to include the command hatch run
check-bundle-imports in the proper place (e.g., after yaml-lint or before
verify-modules-signature) so the documented canonical order matches the updated
pre-commit flow and local validation checklist; modify the ordered list under
"Quality gate order" to insert hatch run check-bundle-imports and ensure
surrounding steps (hatch run yaml-lint and hatch run verify-modules-signature)
remain intact.

In `@docs/agent-rules/60-github-change-governance.md`:
- Around line 62-63: Replace the vague “about five minutes” with a precise
freshness rule: treat .specfact/backlog/github_hierarchy_cache.md as stale if
its recorded timestamp (use an explicit field like last_synced_at in the cache
file or the file mtime) is older than 300 seconds (5 * 60) compared to the
current UTC time; update the text and any checks that call python
scripts/sync_github_hierarchy_cache.py to compare UTC now against last_synced_at
(or mtime) using seconds to decide whether to run the sync.

In `@docs/agent-rules/70-release-commit-and-docs.md`:
- Line 45: Update Step 1 so branch-prefix guidance matches the bootstrap rules:
allow branches rooted from origin/dev with prefixes feature/*, bugfix/*,
hotfix/*, or chore/* (and optionally note the expected worktree location under
../specfact-cli-modules-worktrees/) — or explicitly state if restricting to only
feature/hotfix is intentional; modify the Step 1 text (the line "Branch from
`origin/dev` into a feature or hotfix branch.") to enumerate the allowed
prefixes or add the clarification.

In `@openspec/CHANGE_ORDER.md`:
- Line 78: The CHANGE_ORDER.md contains a pending entry for governance-03
(identifier governance-03-github-hierarchy-cache) but this change is archived;
remove the governance-03 row from the Pending table (or move it into an
Archived/Removed section) and update any parent/paired references (e.g., the
Parent Feature link to `#163` and paired specfact-cli#491 mention) so the pending
table reflects only active change artifacts and avoids drift.

In
`@openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/specs/backlog-sync/spec.md`:
- Around line 1-4: Add a top-level heading and ensure blank lines surround each
heading in the spec to satisfy markdown validation: insert a top-level H1 (e.g.,
"Archived Specs" or similar) above the existing "## MODIFIED Requirements", and
add a single blank line before and after each heading such as "## MODIFIED
Requirements" and "### Requirement: Restore backlog sync command functionality"
(and other headings referenced on lines 3, 12, 17, 21, 25, 31) so the `spec.md`
file, which mentions `specfact backlog sync`, has proper spacing and a top-level
heading.

In
`@openspec/changes/governance-04-deterministic-agent-governance-loading/CHANGE_VALIDATION.md`:
- Around line 27-34: Update the validation summary so it does not claim PASS
when the mandatory full review is failing: change the header/result from
"Result: PASS" to indicate PENDING/BLOCKED and add a clear note that
`.specfact/code-review.json` produced 934 findings and the full-review gate must
pass before marking the change validated; keep the existing details about
`.specfact/code-review.changed.json` passing and the commands used (`hatch run
specfact code review run --json --out .specfact/code-review.json` and the
changed-scope command) so readers see both outcomes and the required action to
re-run the full command until the full review passes.

In
`@openspec/changes/governance-04-deterministic-agent-governance-loading/proposal.md`:
- Around line 1-3: Add a top-level Markdown title before the existing "## Why"
heading to satisfy markdownlint and improve document structure; insert a line
like "# Proposal: Deterministic Agent Governance Loading" at the top of the
proposal (keeping the existing "## Why" section intact) so the document begins
with a single H1 heading.

In
`@openspec/changes/governance-04-deterministic-agent-governance-loading/specs/agent-governance-loading/spec.md`:
- Around line 1-14: The spec is missing a top-level heading; open
specs/agent-governance-loading/spec.md and add a top-level H1 heading
"Specification: Agent Governance Loading" above the existing "## ADDED
Requirements" line so the document conforms to markdownlint and matches the
pattern used in proposal.md; ensure the exact heading text is used and placed as
the first non-blank line of the file.

In
`@openspec/changes/governance-04-deterministic-agent-governance-loading/TDD_EVIDENCE.md`:
- Around line 44-47: Summary: The full-repo SpecFact quality gate still fails
(934 findings) causing release promotion to be blocked; either fix findings or
add an approved exception. Fix: run the exact verification command shown (`hatch
run specfact code review run --json --out .specfact/code-review.json --scope
full`) to regenerate `.specfact/code-review.json`, triage and remediate the
reported findings (start with high-severity items such as the legacy
`packages/specfact-backlog/src/specfact_backlog/backlog/commands.py` complexity
issues), or if remediation is infeasible create an explicit, approved exception
record in the release checklist for this PR referencing task `4.2` and attach
the `.specfact/code-review.json` artifact and justification; update the PR
description/checklist to point to the exception and ensure an approver signs off
before merge.

In
`@openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.md`:
- Around line 3-6: The markdown headings are missing required blank lines
(MD022) which breaks markdownlint; update the spec by inserting a single blank
line after the "Requirement: Backlog add local artifact helpers SHALL preserve
user-managed content" heading and another blank line after the "Scenario:
Existing local config is not silently replaced" heading so each heading is
followed by an empty line, ensuring the document adheres to markdownlint rules.

In
`@openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.md`:
- Around line 1-6: Add a top-level H1 and ensure blank lines surround the
existing headings to satisfy markdownlint (MD041/MD022): insert a single H1 at
the top of the file (for example "Backlog sync requirements" or similar), then
ensure there is a blank line before and after "## ADDED Requirements", and add
blank lines before and after "### Requirement: Backlog sync local export paths
SHALL avoid silent overwrites" and before and after "#### Scenario: Existing
export target produces conflict or safe merge" so each heading has the required
surrounding blank lines.

In `@openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.md`:
- Around line 23-25: Reorder the checklist so quality gates run in the canonical
sequence: ensure the `hatch run format`, `hatch run type-check`, and `hatch run
lint` remain first, then list `hatch run yaml-lint` followed immediately by
`verify-modules-signature` (add or rename the step to `verify-modules-signature`
if needed), then run `hatch run contract-test`, then the relevant
`smart-test`/`test` coverage, and finally the `.specfact/code-review.json`
review step; move the version bump / re-sign changed manifests remediation (the
current 4.4) to immediately after `verify-modules-signature` so package
version/signature fixes occur before `contract-test`, and keep recording the
final review timestamp in `TDD_EVIDENCE.md` or PR notes as the last action.

In `@openspec/specs/github-hierarchy-cache/spec.md`:
- Around line 3-5: The Purpose section of this spec file (heading "Purpose") is
still "TBD" and must be replaced with a self-contained description of what the
github-hierarchy-cache spec standardizes; update the "Purpose" heading to a
concise summary that explains scope, intended behavior, and how it relates to
archived-change governance-03-github-hierarchy-cache, and ensure the
"Requirements" section references any CHANGE_ORDER, drift/shipping constraints
and the openspec/**/*.md conventions so the spec is complete before merging.

In `@README.md`:
- Line 56: Update the README run-sequence so the standalone final code-review
gate is explicitly listed and matches the pre-commit path: add the command
"hatch run specfact code review run --json --out .specfact/code-review.json" (or
the equivalent "specfact code review run --json --out
.specfact/code-review.json" if already run in a hatch context) into the top “Run
this sequence” block after tests, ensuring the sequence reads: format →
type-check → lint → yaml-lint → verify-modules-signature → contract-test →
smart-test → test → specfact code review; mention the same helper behavior
referenced by pre-commit-quality-checks.sh block2 and
scripts/pre_commit_code_review.py so manual local validation matches the
required governance order.

In `@scripts/pre-commit-quality-checks.sh`:
- Around line 149-169: The run_code_review_gate function only collects staged
Python files via staged_python_files and so skips review for non-Python contract
changes; change it to gather all review-relevant staged paths (not just
*.py/*.pyi) by calling the staged files helper that returns all staged paths
(e.g., staged_files or staged_paths) and filter/include files under packages/,
registry/, scripts/, tools/, tests/, and openspec/changes/* (but exclude any
TDD_EVIDENCE.md) before invoking scripts/pre_commit_code_review.py; ensure the
collected list is passed to scripts/pre_commit_code_review.py the same way
${py_array[@]} currently is and update the info/warn messages to reflect the
broader file set in run_code_review_gate.
- Around line 209-218: The current short-circuit in run_block2() uses
check_safe_change() too broadly and lets edits to tooling/config (e.g.,
pyproject.toml or this pre-commit script) skip the review and contract-test
decision; narrow the safe-change logic so tooling/config files do not trigger
the fast path by updating check_safe_change() usage or its predicate inside
run_block2() to exclude repo metadata that defines the quality pipeline (ensure
changes to pyproject.toml, scripts/pre-commit-quality-checks.sh, and other
pipeline-defining files bypass the safe path), then keep print_block2_overview,
run_code_review_gate and run_contract_tests_visible executing for those changes.

In `@scripts/sync_github_hierarchy_cache.py`:
- Around line 336-348: The fingerprint currently includes updated_at (causing
unnecessary churn) and omits fields that affect rendered output; in
compute_hierarchy_fingerprint replace updated_at with the exact fields used when
rendering the cache (e.g., include issue.url and issue.summary and any other
rendered inputs you write out such as title, labels, parent_number,
child_numbers) and keep deterministic ordering (sorted labels, sorted children
by number) so the hash reflects only rendered-output-relevant data; adjust the
canonical_rows construction in compute_hierarchy_fingerprint/HierarchyIssue
accordingly.
- Around line 98-100: The GraphQL subIssues connection currently uses
subIssues(first: 100) without pageInfo and the code does not handle nested
pagination, causing silent truncation; update the query to request pageInfo {
hasNextPage endCursor } for subIssues and modify the GraphQL-fetching logic that
builds the issue hierarchy (the code handling the subIssues connection /
response) to iterate using endCursor while hasNextPage to fetch all pages,
merging nodes across pages, or alternatively detect hasNextPage and raise a
clear error to prevent silent truncation; ensure the final hierarchy/fingerprint
includes all children and that any error path logs the problematic parent issue
number/URL.

In `@scripts/validate_agent_rule_applies_when.py`:
- Around line 55-59: path.read_text can raise OSError/UnicodeDecodeError and
currently crashes the validator; wrap the call to
path.read_text(encoding="utf-8") in a try/except that catches OSError and
UnicodeDecodeError, append a structured validation entry to the existing errors
list (e.g. f"{path.name}: failed to read file: {err}") and continue the loop,
then only call _parse_frontmatter(text) if read succeeded so parsed handling
remains unchanged.
- Around line 66-68: In validate_agent_rule_applies_when
(scripts/validate_agent_rule_applies_when.py) stop coercing list items to text:
when raw is a list, validate each entry is either a str or None and if any item
has a different type raise a TypeError with a clear message identifying
"applies_when" entries; only after validation build signals as the list of
strings (i.e., keep items as-is, not str(item)) and filter out None. This
replaces the current signals = [str(item) for item in raw if item is not None]
with explicit type checks and an immediate error on malformed types.

In `@src/specfact_cli_modules/dev_bootstrap.py`:
- Around line 58-62: The code uses os.environ.setdefault(...) which preserves
any previously exported SPECFACT_MODULES_REPO / SPECFACT_REPO_ROOT; instead,
always overwrite with the current checkout values: replace
os.environ.setdefault("SPECFACT_MODULES_REPO", str(resolved)) with an assignment
that sets os.environ["SPECFACT_MODULES_REPO"] = str(resolved), and if core is
not None replace os.environ.setdefault("SPECFACT_REPO_ROOT", str(core)) with
os.environ["SPECFACT_REPO_ROOT"] = str(core); locate these changes around the
resolved = repo_root.resolve() and core = resolve_core_repo(repo_root) usage in
dev_bootstrap.py.

In `@tests/unit/docs/test_agent_rules_governance.py`:
- Around line 68-74: The test function
test_agents_references_canonical_rule_docs verifies AGENTS.md contains specific
doc references and section text but the file lacks a trailing newline; open
AGENTS.md and add a single POSIX-compliant newline at EOF (ensure the file ends
with "\n") so the test environment and tools that expect a trailing newline
won't complain when running test_agents_references_canonical_rule_docs.

In `@tests/unit/scripts/test_pre_commit_code_review.py`:
- Around line 89-98: Extract the repeated mocked report payload into a single
shared test fixture/object and reuse it instead of inlining it twice;
specifically create a variable (e.g., sample_review_report =
{"overall_verdict":"FAIL","findings":[{"severity":"error","rule":"e1"},{"severity":"warning","rule":"w1"}]})
near the top of the test module and replace the inline literal passed to
_write_sample_review_report(repo_root, ...) with that variable in all
occurrences so the test_pre_commit_code_review.py assertions stay consistent and
easier to maintain.

In `@tests/unit/scripts/test_sync_github_hierarchy_cache.py`:
- Around line 459-474: Wrap the test body in a try/finally (or use a teardown
fixture) so cleanup always runs: after setting subprocess.run to _no_git via
monkeypatch.setattr and importing the module via _load_script_module(), ensure
_load_script_module.cache_clear() and
sys.modules.pop("sync_github_hierarchy_cache", None) are invoked in a finally
block; this guarantees that the monkeypatched subprocess.run is restored and the
import cache is cleared even if the assertion in
test_default_repo_name_falls_back_when_git_unavailable fails.

In `@tests/unit/tools/test_contract_first_smart_test.py`:
- Around line 44-61: Add a third "happy-path" unit test in
tests/unit/tools/test_contract_first_smart_test.py that patches
cfst_mod._git_staged_names to return a contract-relevant path (e.g.,
"contracts/some_contract.yaml" or any path your code treats as contract-related)
and assert cfst_mod._contract_test_status() == 1; reference the existing tests
for structure and reuse monkeypatch and the cfst_mod fixture, and ensure the new
test name makes intent clear (e.g.,
test_contract_test_status_returns_one_for_relevant_staged).

---

Outside diff comments:
In `@openspec/specs/backlog-sync/spec.md`:
- Around line 7-33: Update the spec text to explicitly pin the repo-local
hierarchy cache path and state file names so adapters and specfact-cli share a
canonical contract: replace ambiguous instances of "repo-local hierarchy cache"
with the explicit paths `.specfact/backlog/github_hierarchy_cache.md` for the
human-readable hierarchy and the accompanying state JSON (e.g.,
`.specfact/backlog/github_hierarchy_cache.state.json`), and add a short sentence
in the "Cache-first hierarchy lookup for parent issue assignment" scenario
noting that tools MUST read/write those exact files and only fall back to GitHub
when those files are missing or stale; reference the command `specfact backlog
sync` and the alias `specfact backlog ceremony sync` so the change is visible to
consumers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4f777531-c9df-4487-8b32-8337cb88bac1

📥 Commits

Reviewing files that changed from the base of the PR and between 5677559 and 6cd6564.

📒 Files selected for processing (61)
  • .cursorrules
  • .github/copilot-instructions.md
  • .pre-commit-config.yaml
  • AGENTS.md
  • CLAUDE.md
  • README.md
  • docs/_data/nav.yml
  • docs/agent-rules/05-non-negotiable-checklist.md
  • docs/agent-rules/10-session-bootstrap.md
  • docs/agent-rules/20-repository-context.md
  • docs/agent-rules/30-worktrees-and-branching.md
  • docs/agent-rules/40-openspec-and-tdd.md
  • docs/agent-rules/50-quality-gates-and-review.md
  • docs/agent-rules/60-github-change-governance.md
  • docs/agent-rules/70-release-commit-and-docs.md
  • docs/agent-rules/80-current-guidance-catalog.md
  • docs/agent-rules/INDEX.md
  • openspec/CHANGE_ORDER.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/.openspec.yaml
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/CHANGE_VALIDATION.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/TDD_EVIDENCE.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/design.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/proposal.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/specs/backlog-sync/spec.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/specs/github-hierarchy-cache/spec.md
  • openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/tasks.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/.openspec.yaml
  • openspec/changes/governance-04-deterministic-agent-governance-loading/CHANGE_VALIDATION.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/TDD_EVIDENCE.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/design.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/proposal.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/specs/agent-governance-loading/spec.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/specs/github-hierarchy-cache/spec.md
  • openspec/changes/governance-04-deterministic-agent-governance-loading/tasks.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/.openspec.yaml
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/CHANGE_VALIDATION.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/design.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/proposal.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/runtime-artifact-write-safety/spec.md
  • openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.md
  • openspec/config.yaml
  • openspec/specs/backlog-sync/spec.md
  • openspec/specs/github-hierarchy-cache/spec.md
  • pyproject.toml
  • scripts/pre-commit-quality-checks.sh
  • scripts/pre_commit_code_review.py
  • scripts/sync_github_hierarchy_cache.py
  • scripts/validate_agent_rule_applies_when.py
  • src/specfact_cli_modules/dev_bootstrap.py
  • tests/__init__.py
  • tests/conftest.py
  • tests/unit/docs/test_agent_rules_governance.py
  • tests/unit/scripts/test_pre_commit_code_review.py
  • tests/unit/scripts/test_sync_github_hierarchy_cache.py
  • tests/unit/scripts/test_validate_agent_rule_applies_when.py
  • tests/unit/test_dev_bootstrap.py
  • tests/unit/test_pre_commit_quality_parity.py
  • tests/unit/tools/test_contract_first_smart_test.py
  • tools/contract_first_smart_test.py

@djm81
Copy link
Copy Markdown
Contributor Author

djm81 commented Apr 13, 2026

@cursor Check the code review findings and fix if applicable and valid, then create a PR to dev branch to remediate:

  1. Codex review:
    pyproject.toml
    Comment on lines 18 to 22
    dependencies = [
    "json5>=0.9.28",
    "icontract>=2.7.1",
    "pytest>=8.4.2",
    "pytest-cov>=7.0.0",
    @chatgpt-codex-connector
    chatgpt-codex-connector bot
    10 hours ago
    P1 Badge Declare beartype in the default hatch environment

The new governance scripts import beartype unconditionally (scripts/sync_github_hierarchy_cache.py and scripts/validate_agent_rule_applies_when.py), but the default Hatch environment dependencies added here do not include beartype. In a fresh checkout (or any environment that has not separately installed specfact-cli), running python scripts/sync_github_hierarchy_cache.py (now required by AGENTS bootstrap) or hatch run validate-agent-rule-signals fails immediately with ModuleNotFoundError: beartype, so the new workflow cannot run as documented.

  1. CoderabbitAI review (25 findings):

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @docs/agent-rules/50-quality-gates-and-review.md:

  • Around line 39-49: The quality gate list omits the bundle-import validation
    step; update the "Quality gate order" sequence to include the command hatch run
    check-bundle-imports in the proper place (e.g., after yaml-lint or before
    verify-modules-signature) so the documented canonical order matches the updated
    pre-commit flow and local validation checklist; modify the ordered list under
    "Quality gate order" to insert hatch run check-bundle-imports and ensure
    surrounding steps (hatch run yaml-lint and hatch run verify-modules-signature)
    remain intact.

In @docs/agent-rules/60-github-change-governance.md:

  • Around line 62-63: Replace the vague “about five minutes” with a precise
    freshness rule: treat .specfact/backlog/github_hierarchy_cache.md as stale if
    its recorded timestamp (use an explicit field like last_synced_at in the cache
    file or the file mtime) is older than 300 seconds (5 * 60) compared to the
    current UTC time; update the text and any checks that call python
    scripts/sync_github_hierarchy_cache.py to compare UTC now against last_synced_at
    (or mtime) using seconds to decide whether to run the sync.

In @docs/agent-rules/70-release-commit-and-docs.md:

  • Line 45: Update Step 1 so branch-prefix guidance matches the bootstrap rules:
    allow branches rooted from origin/dev with prefixes feature/, bugfix/,
    hotfix/, or chore/ (and optionally note the expected worktree location under
    ../specfact-cli-modules-worktrees/) — or explicitly state if restricting to only
    feature/hotfix is intentional; modify the Step 1 text (the line "Branch from
    origin/dev into a feature or hotfix branch.") to enumerate the allowed
    prefixes or add the clarification.

In @openspec/CHANGE_ORDER.md:

  • Line 78: The CHANGE_ORDER.md contains a pending entry for governance-03
    (identifier governance-03-github-hierarchy-cache) but this change is archived;
    remove the governance-03 row from the Pending table (or move it into an
    Archived/Removed section) and update any parent/paired references (e.g., the
    Parent Feature link to #163 and paired specfact-cli#491 mention) so the pending
    table reflects only active change artifacts and avoids drift.

In
@openspec/changes/archive/2026-04-09-governance-03-github-hierarchy-cache/specs/backlog-sync/spec.md:

  • Around line 1-4: Add a top-level heading and ensure blank lines surround each
    heading in the spec to satisfy markdown validation: insert a top-level H1 (e.g.,
    "Archived Specs" or similar) above the existing "## MODIFIED Requirements", and
    add a single blank line before and after each heading such as "## MODIFIED
    Requirements" and "### Requirement: Restore backlog sync command functionality"
    (and other headings referenced on lines 3, 12, 17, 21, 25, 31) so the spec.md
    file, which mentions specfact backlog sync, has proper spacing and a top-level
    heading.

In
@openspec/changes/governance-04-deterministic-agent-governance-loading/CHANGE_VALIDATION.md:

  • Around line 27-34: Update the validation summary so it does not claim PASS
    when the mandatory full review is failing: change the header/result from
    "Result: PASS" to indicate PENDING/BLOCKED and add a clear note that
    .specfact/code-review.json produced 934 findings and the full-review gate must
    pass before marking the change validated; keep the existing details about
    .specfact/code-review.changed.json passing and the commands used (hatch run specfact code review run --json --out .specfact/code-review.json and the
    changed-scope command) so readers see both outcomes and the required action to
    re-run the full command until the full review passes.

In
@openspec/changes/governance-04-deterministic-agent-governance-loading/proposal.md:

  • Around line 1-3: Add a top-level Markdown title before the existing "## Why"
    heading to satisfy markdownlint and improve document structure; insert a line
    like "# Proposal: Deterministic Agent Governance Loading" at the top of the
    proposal (keeping the existing "## Why" section intact) so the document begins
    with a single H1 heading.

In
@openspec/changes/governance-04-deterministic-agent-governance-loading/specs/agent-governance-loading/spec.md:

  • Around line 1-14: The spec is missing a top-level heading; open
    specs/agent-governance-loading/spec.md and add a top-level H1 heading
    "Specification: Agent Governance Loading" above the existing "## ADDED
    Requirements" line so the document conforms to markdownlint and matches the
    pattern used in proposal.md; ensure the exact heading text is used and placed as
    the first non-blank line of the file.

In
@openspec/changes/governance-04-deterministic-agent-governance-loading/TDD_EVIDENCE.md:

  • Around line 44-47: Summary: The full-repo SpecFact quality gate still fails
    (934 findings) causing release promotion to be blocked; either fix findings or
    add an approved exception. Fix: run the exact verification command shown (hatch run specfact code review run --json --out .specfact/code-review.json --scope full) to regenerate .specfact/code-review.json, triage and remediate the
    reported findings (start with high-severity items such as the legacy
    packages/specfact-backlog/src/specfact_backlog/backlog/commands.py complexity
    issues), or if remediation is infeasible create an explicit, approved exception
    record in the release checklist for this PR referencing task 4.2 and attach
    the .specfact/code-review.json artifact and justification; update the PR
    description/checklist to point to the exception and ensure an approver signs off
    before merge.

In
@openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-add/spec.md:

  • Around line 3-6: The markdown headings are missing required blank lines
    (MD022) which breaks markdownlint; update the spec by inserting a single blank
    line after the "Requirement: Backlog add local artifact helpers SHALL preserve
    user-managed content" heading and another blank line after the "Scenario:
    Existing local config is not silently replaced" heading so each heading is
    followed by an empty line, ensuring the document adheres to markdownlint rules.

In
@openspec/changes/project-runtime-01-safe-artifact-write-policy/specs/backlog-sync/spec.md:

  • Around line 1-6: Add a top-level H1 and ensure blank lines surround the
    existing headings to satisfy markdownlint (MD041/MD022): insert a single H1 at
    the top of the file (for example "Backlog sync requirements" or similar), then
    ensure there is a blank line before and after "## ADDED Requirements", and add
    blank lines before and after "### Requirement: Backlog sync local export paths
    SHALL avoid silent overwrites" and before and after "#### Scenario: Existing
    export target produces conflict or safe merge" so each heading has the required
    surrounding blank lines.

In @openspec/changes/project-runtime-01-safe-artifact-write-policy/tasks.md:

  • Around line 23-25: Reorder the checklist so quality gates run in the canonical
    sequence: ensure the hatch run format, hatch run type-check, and hatch run lint remain first, then list hatch run yaml-lint followed immediately by
    verify-modules-signature (add or rename the step to verify-modules-signature
    if needed), then run hatch run contract-test, then the relevant
    smart-test/test coverage, and finally the .specfact/code-review.json
    review step; move the version bump / re-sign changed manifests remediation (the
    current 4.4) to immediately after verify-modules-signature so package
    version/signature fixes occur before contract-test, and keep recording the
    final review timestamp in TDD_EVIDENCE.md or PR notes as the last action.

In @openspec/specs/github-hierarchy-cache/spec.md:

  • Around line 3-5: The Purpose section of this spec file (heading "Purpose") is
    still "TBD" and must be replaced with a self-contained description of what the
    github-hierarchy-cache spec standardizes; update the "Purpose" heading to a
    concise summary that explains scope, intended behavior, and how it relates to
    archived-change governance-03-github-hierarchy-cache, and ensure the
    "Requirements" section references any CHANGE_ORDER, drift/shipping constraints
    and the openspec/**/*.md conventions so the spec is complete before merging.

In @README.md:

  • Line 56: Update the README run-sequence so the standalone final code-review
    gate is explicitly listed and matches the pre-commit path: add the command
    "hatch run specfact code review run --json --out .specfact/code-review.json" (or
    the equivalent "specfact code review run --json --out
    .specfact/code-review.json" if already run in a hatch context) into the top “Run
    this sequence” block after tests, ensuring the sequence reads: format →
    type-check → lint → yaml-lint → verify-modules-signature → contract-test →
    smart-test → test → specfact code review; mention the same helper behavior
    referenced by pre-commit-quality-checks.sh block2 and
    scripts/pre_commit_code_review.py so manual local validation matches the
    required governance order.

In @scripts/pre-commit-quality-checks.sh:

  • Around line 149-169: The run_code_review_gate function only collects staged
    Python files via staged_python_files and so skips review for non-Python contract
    changes; change it to gather all review-relevant staged paths (not just
    .py/.pyi) by calling the staged files helper that returns all staged paths
    (e.g., staged_files or staged_paths) and filter/include files under packages/,
    registry/, scripts/, tools/, tests/, and openspec/changes/* (but exclude any
    TDD_EVIDENCE.md) before invoking scripts/pre_commit_code_review.py; ensure the
    collected list is passed to scripts/pre_commit_code_review.py the same way
    ${py_array[@]} currently is and update the info/warn messages to reflect the
    broader file set in run_code_review_gate.
  • Around line 209-218: The current short-circuit in run_block2() uses
    check_safe_change() too broadly and lets edits to tooling/config (e.g.,
    pyproject.toml or this pre-commit script) skip the review and contract-test
    decision; narrow the safe-change logic so tooling/config files do not trigger
    the fast path by updating check_safe_change() usage or its predicate inside
    run_block2() to exclude repo metadata that defines the quality pipeline (ensure
    changes to pyproject.toml, scripts/pre-commit-quality-checks.sh, and other
    pipeline-defining files bypass the safe path), then keep print_block2_overview,
    run_code_review_gate and run_contract_tests_visible executing for those changes.

In @scripts/sync_github_hierarchy_cache.py:

  • Around line 336-348: The fingerprint currently includes updated_at (causing
    unnecessary churn) and omits fields that affect rendered output; in
    compute_hierarchy_fingerprint replace updated_at with the exact fields used when
    rendering the cache (e.g., include issue.url and issue.summary and any other
    rendered inputs you write out such as title, labels, parent_number,
    child_numbers) and keep deterministic ordering (sorted labels, sorted children
    by number) so the hash reflects only rendered-output-relevant data; adjust the
    canonical_rows construction in compute_hierarchy_fingerprint/HierarchyIssue
    accordingly.
  • Around line 98-100: The GraphQL subIssues connection currently uses
    subIssues(first: 100) without pageInfo and the code does not handle nested
    pagination, causing silent truncation; update the query to request pageInfo {
    hasNextPage endCursor } for subIssues and modify the GraphQL-fetching logic that
    builds the issue hierarchy (the code handling the subIssues connection /
    response) to iterate using endCursor while hasNextPage to fetch all pages,
    merging nodes across pages, or alternatively detect hasNextPage and raise a
    clear error to prevent silent truncation; ensure the final hierarchy/fingerprint
    includes all children and that any error path logs the problematic parent issue
    number/URL.

In @scripts/validate_agent_rule_applies_when.py:

  • Around line 55-59: path.read_text can raise OSError/UnicodeDecodeError and
    currently crashes the validator; wrap the call to
    path.read_text(encoding="utf-8") in a try/except that catches OSError and
    UnicodeDecodeError, append a structured validation entry to the existing errors
    list (e.g. f"{path.name}: failed to read file: {err}") and continue the loop,
    then only call _parse_frontmatter(text) if read succeeded so parsed handling
    remains unchanged.
  • Around line 66-68: In validate_agent_rule_applies_when
    (scripts/validate_agent_rule_applies_when.py) stop coercing list items to text:
    when raw is a list, validate each entry is either a str or None and if any item
    has a different type raise a TypeError with a clear message identifying
    "applies_when" entries; only after validation build signals as the list of
    strings (i.e., keep items as-is, not str(item)) and filter out None. This
    replaces the current signals = [str(item) for item in raw if item is not None]
    with explicit type checks and an immediate error on malformed types.

In @src/specfact_cli_modules/dev_bootstrap.py:

  • Around line 58-62: The code uses os.environ.setdefault(...) which preserves
    any previously exported SPECFACT_MODULES_REPO / SPECFACT_REPO_ROOT; instead,
    always overwrite with the current checkout values: replace
    os.environ.setdefault("SPECFACT_MODULES_REPO", str(resolved)) with an assignment
    that sets os.environ["SPECFACT_MODULES_REPO"] = str(resolved), and if core is
    not None replace os.environ.setdefault("SPECFACT_REPO_ROOT", str(core)) with
    os.environ["SPECFACT_REPO_ROOT"] = str(core); locate these changes around the
    resolved = repo_root.resolve() and core = resolve_core_repo(repo_root) usage in
    dev_bootstrap.py.

In @tests/unit/docs/test_agent_rules_governance.py:

  • Around line 68-74: The test function
    test_agents_references_canonical_rule_docs verifies AGENTS.md contains specific
    doc references and section text but the file lacks a trailing newline; open
    AGENTS.md and add a single POSIX-compliant newline at EOF (ensure the file ends
    with "\n") so the test environment and tools that expect a trailing newline
    won't complain when running test_agents_references_canonical_rule_docs.

In @tests/unit/scripts/test_pre_commit_code_review.py:

  • Around line 89-98: Extract the repeated mocked report payload into a single
    shared test fixture/object and reuse it instead of inlining it twice;
    specifically create a variable (e.g., sample_review_report =
    {"overall_verdict":"FAIL","findings":[{"severity":"error","rule":"e1"},{"severity":"warning","rule":"w1"}]})
    near the top of the test module and replace the inline literal passed to
    _write_sample_review_report(repo_root, ...) with that variable in all
    occurrences so the test_pre_commit_code_review.py assertions stay consistent and
    easier to maintain.

In @tests/unit/scripts/test_sync_github_hierarchy_cache.py:

  • Around line 459-474: Wrap the test body in a try/finally (or use a teardown
    fixture) so cleanup always runs: after setting subprocess.run to _no_git via
    monkeypatch.setattr and importing the module via _load_script_module(), ensure
    _load_script_module.cache_clear() and
    sys.modules.pop("sync_github_hierarchy_cache", None) are invoked in a finally
    block; this guarantees that the monkeypatched subprocess.run is restored and the
    import cache is cleared even if the assertion in
    test_default_repo_name_falls_back_when_git_unavailable fails.

In @tests/unit/tools/test_contract_first_smart_test.py:

  • Around line 44-61: Add a third "happy-path" unit test in
    tests/unit/tools/test_contract_first_smart_test.py that patches
    cfst_mod._git_staged_names to return a contract-relevant path (e.g.,
    "contracts/some_contract.yaml" or any path your code treats as contract-related)
    and assert cfst_mod._contract_test_status() == 1; reference the existing tests
    for structure and reuse monkeypatch and the cfst_mod fixture, and ensure the new
    test name makes intent clear (e.g.,
    test_contract_test_status_returns_one_for_relevant_staged).

Outside diff comments:
In @openspec/specs/backlog-sync/spec.md:

  • Around line 7-33: Update the spec text to explicitly pin the repo-local
    hierarchy cache path and state file names so adapters and specfact-cli share a
    canonical contract: replace ambiguous instances of "repo-local hierarchy cache"
    with the explicit paths .specfact/backlog/github_hierarchy_cache.md for the
    human-readable hierarchy and the accompanying state JSON (e.g.,
    .specfact/backlog/github_hierarchy_cache.state.json), and add a short sentence
    in the "Cache-first hierarchy lookup for parent issue assignment" scenario
    noting that tools MUST read/write those exact files and only fall back to GitHub
    when those files are missing or stale; reference the command specfact backlog sync and the alias specfact backlog ceremony sync so the change is visible to
    consumers.

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 13, 2026

Here is what I did and where it landed.

PR

PR #184 — branch cursor/coderabbit-remediation-011edev

Codex (beartype)

  • Added beartype>=0.22.0 to the default Hatch env in pyproject.toml so python scripts/sync_github_hierarchy_cache.py and hatch run validate-agent-rule-signals work without a separate specfact-cli install.

CodeRabbit / tooling (high impact)

  • scripts/sync_github_hierarchy_cache.py: Paginates subIssues via a dedicated GraphQL query (no silent >100-child truncation). compute_hierarchy_fingerprint now hashes fields that match rendered output (url, summary, labels, parent/children) and drops updated_at from the fingerprint payload.
  • scripts/pre-commit-quality-checks.sh: check_safe_change no longer treats pyproject.toml / scripts/pre-commit-quality-checks.sh / scripts/pre_commit_code_review.py / tools/contract_first_smart_test.py as “safe” for skipping Block 2. run_code_review_gate passes staged paths under packages/, registry/, scripts/, tools/, tests/, openspec/changes/ (skips TDD_EVIDENCE.md).
  • scripts/pre_commit_code_review.py: filter_review_gate_paths mirrors that policy (replaces Python-only filtering).
  • src/specfact_cli_modules/dev_bootstrap.py: apply_specfact_workspace_env always sets SPECFACT_MODULES_REPO / SPECFACT_REPO_ROOT (no stale setdefault). Test updated accordingly.
  • scripts/validate_agent_rule_applies_when.py: Safe file reads; applies_when list entries must be str or null (non-strings are reported as validation errors).
  • tools/contract_first_smart_test.py: Staged paths under contracts/ trigger contract-test (with tests).

Docs / OpenSpec

  • Quality gate order includes check-bundle-imports; README sequence adds check-bundle-imports and explicit hatch run specfact code review run --json --out .specfact/code-review.json.
  • openspec/specs/backlog-sync/spec.md: Pins .specfact/backlog/github_hierarchy_cache.md and .specfact/backlog/github_hierarchy_cache_state.json; references specfact backlog sync / ceremony alias.
  • openspec/specs/github-hierarchy-cache/spec.md: Replaces TBD purpose with a real scope statement.
  • openspec/CHANGE_ORDER.md: Moves archived governance-03 to Implemented; trims pending row; keeps #491 reference on governance-04 baseline text.
  • Markdown structure fixes in archived governance-03 backlog-sync spec, governance-04 proposal/spec/validation, project-runtime OpenSpec specs/tasks; CHANGE_VALIDATION / TDD_EVIDENCE clarify full-review PENDING/BLOCKED.

Tests / gates run locally

  • hatch run format, type-check, lint, yaml-lint, check-bundle-imports, hatch run test545 passed (project test helper runs full tree).
  • verify-modules-signature --require-signature failed in this environment (missing public key for bundle verification), noted in the PR body.
Open in Web Open in Cursor 

- Add beartype to default Hatch env so standalone scripts import cleanly.
- Hierarchy cache: paginate subIssues; fingerprint rendered fields (not updated_at).
- Pre-commit Block 2: narrow safe-change skip; review gate uses staged contract paths.
- apply_specfact_workspace_env always pins SPECFACT_* to current checkout.
- validate_agent_rule_applies_when: robust reads; strict applies_when list types.
- contract_first_smart_test: treat contracts/ as contract-relevant.
- Docs/openspec: quality gate order, cache freshness, CHANGE_ORDER, backlog-sync paths.

Co-authored-by: Dom <djm81@users.noreply.github.com>
cursoragent and others added 3 commits April 13, 2026 10:21
Codex P2: pre_commit_code_review.py and contract_first_smart_test.py must
not bypass Block 2 when staged alone—they define the review and contract-test
gates.

Co-authored-by: Dom <djm81@users.noreply.github.com>
- project-runtime tasks: add check-bundle-imports; explicit full code review step.
- Agent rules: append specfact code review to canonical gate order with evidence path.
- sync_github_hierarchy_cache: wrap subIssues JSON parse in RuntimeError for main().
- dev_bootstrap: pop SPECFACT_REPO_ROOT when core is unresolved; regression test.

Co-authored-by: Dom <djm81@users.noreply.github.com>
fix: Codex/CodeRabbit remediation (beartype, hierarchy cache, pre-commit review gate)
@djm81 djm81 merged commit 9bbe588 into main Apr 13, 2026
19 of 20 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in SpecFact CLI Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Change] governance-04: Deterministic agent governance loading [Change] Local GitHub hierarchy cache for OpenSpec planning

2 participants